use crate::icon;
use crate::config;
use crate::window_state::WindowState;

use std::sync::{Arc, Mutex};
use tray_icon::{
    menu::{Menu, MenuEvent, MenuItem, MenuId},
    Icon as TrayIcon, TrayIconBuilder,
};

pub struct TrayIconManager {
    _tray_icon: tray_icon::TrayIcon,
    window_state: Arc<Mutex<WindowState>>,
}

impl TrayIconManager {
    pub fn new(window_state: Arc<Mutex<WindowState>>) -> Result<Self, Box<dyn std::error::Error>> {
        let icon = Self::create_icon()?;
        let (tray_menu, show_id, quit_id) = Self::create_menu()?;

        let _tray_icon = TrayIconBuilder::new()
            .with_menu(Box::new(tray_menu))
            .with_tooltip(config::APP_NAME)
            .with_icon(icon)
            .build()?;

        // 启动菜单事件处理线程
        let state_clone = window_state.clone();
        std::thread::spawn(move || Self::handle_menu_events(quit_id, show_id, state_clone));

        Ok(Self {
            _tray_icon,
            window_state,
        })
    }

    fn create_icon() -> Result<TrayIcon, Box<dyn std::error::Error>> {
        let icon_size = 32;
        let icon_buffer = icon::create_mobius_icon(icon_size);
        let icon_rgba = icon_buffer.into_raw();
        Ok(TrayIcon::from_rgba(icon_rgba, icon_size, icon_size)?)
    }

    fn create_menu() -> Result<(Menu, MenuId, MenuId), Box<dyn std::error::Error>> {
        let tray_menu = Menu::new();
        let show_item = MenuItem::new("显示", true, None);
        let show_id = show_item.id().clone();
        let quit_item = MenuItem::new("退出", true, None);
        let quit_id = quit_item.id().clone();

        tray_menu.append(&show_item)?;
        tray_menu.append(&quit_item)?;

        Ok((tray_menu, show_id, quit_id))
    }

    fn handle_menu_events(quit_id: MenuId, show_id: MenuId, window_state: Arc<Mutex<WindowState>>) {
        loop {
            if let Ok(event) = MenuEvent::receiver().try_recv() {
                match event.id {
                    id if id == quit_id => std::process::exit(0),
                    id if id == show_id => {
                        if let Ok(mut state) = window_state.lock() {
                            state.show = true;
                        }
                    }
                    _ => {}
                }
            }
        }
    }
}